#include "HighPrecisionInput.h"

HighPrecisionInput::HighPrecisionInput(int keyscount, KEYCODE * pKeyset, HighPrecisionTimer * pHPTimer, float * curTime, int controllertype)
{
	keysetsize = keyscount;
	keystats = new bool[keysetsize];
	pkeyset = pKeyset;
	phptimer = pHPTimer;
	curtime = curTime;
	type = controllertype;
	for (int i = 0; i < keysetsize; i++)
	{
		keystats[i] = false;
	}
}

void HighPrecisionInput::scankeys()
{
	while (isRunning)
	{
		float tmptime = 0;
		if (type == 1) tmptime = *curtime + phptimer->getElapsed();
		else tmptime = phptimer->getElapsed();
		for (int i = 0; i < keysetsize; i++)
		{
			bool keystat = (GetAsyncKeyState(pkeyset[i]) & 0x8000) ? true : false;
			if (keystats[i] != keystat)
			{
				HPKEYEVENT key = { i,keystat,tmptime };
				while (queuelock.test_and_set()) {};
				keyqueue.push_back(key);
				queuelock.clear();
				keystats[i] = keystat;
			}
		}
		this_thread::sleep_for(chrono::nanoseconds(1000));
	}
}

void HighPrecisionInput::start()
{
	isRunning = true;
	queuelock.clear();
	thread thpi(&HighPrecisionInput::scankeys, this);
	thpi.detach();
}

void HighPrecisionInput::stop()
{
	isRunning = false;
}

HighPrecisionInput::HPKEYEVENT HighPrecisionInput::getkey()
{
	while (queuelock.test_and_set()) {};
	vector<HPKEYEVENT>::iterator iter = keyqueue.begin();
	if(iter==keyqueue.end())
	{
		queuelock.clear();
		return HPKEYEVENT{ -1,false,0 };
	}
	else
	{
		HPKEYEVENT keyevent = *iter;
		keyqueue.erase(vector<HPKEYEVENT>::iterator(iter));
		queuelock.clear();
		return keyevent;
	}
}
